﻿package extremefx {
	import extremefx.conditions.requiresNumber;
	import extremefx.extensions.isNullOrEmpty;
	import extremefx.i18n.XString;

	import flash.utils.Proxy;
	import flash.utils.flash_proxy;

	/**	 * @author Marcelo Volmaro	 */	public final class StringBuilder extends Proxy {//		private static const NEW_LINE:String = '\r\n'; //this produces two lines in flash...
		private static const NEW_LINE:String = '\n';
		private var _string:String;
					public function StringBuilder(pText:String = "", pStartIdx:Number = 0, pLength:Number = 0x7fffffff){
			clear();
			_string = pText.substr(pStartIdx, pLength);
		};
		
		override flash_proxy function hasProperty(name:*):Boolean {
	        return _string.charAt(uint(name)) != null;
	    }

		/**
		 * Array access operator: get[index]
		 */
		override flash_proxy function getProperty(name:*):* {
			var idx:uint = uint(name);
			requiresNumber(idx, "index").isLessThan(_string.length);
			return _string.charAt(idx);
	    }
	
		/**
		 * Array access operator: set[index] = value
		 * Overrides a call to change a property's value.
		 */
	    override flash_proxy function setProperty(name:*, value:*):void {
	    	var idx:uint = uint(name);
	    	requiresNumber(idx, "index").isLessThan(_string.length);
			_string.substr(0, idx) + value + _string.substr(idx+1);
	    }
				public function append(pText:String, pStart:Number = 0, pLength:Number = 0x7fffffff):void{			_string += pText.substr(pStart, pLength);		}				public function appendFormat(pText:String, ...args):void{
			args.unshift(pText);			_string += XString.format.apply(null, args);		}				public function appendLine(pText:String = ""):void{
			_string += pText + NEW_LINE;		}
		
		public function appendFormatLine(pText:String, ...args):void{
			args.unshift(pText);//Nasty hack...
			_string += XString.format.apply(null, args) + NEW_LINE;
		}		public function insert(pIndex:Number, pText:String, pCount:Number = 1):void {			if (pCount == 0) return;						var start:String = _string.substr(0, pIndex);			while (pCount--){				start += pText;				}						_string = start + _string.substr(pIndex);		}				public function remove(pStart:Number, pLength:Number):void {
			_string = _string.substr(0, pStart) + _string.substr(pStart + pLength); 		}				public function replace(pOld:String, pNew:String, pStart:Number = 0, pLength:Number = 0x7fffffff):void {			var replaced:String = toString(pStart, pLength).split(pOld).join(pNew);						var start:String = "";			if (pStart != 0){				start = _string.substr(0, pStart);			}						var end:String = "";			if (pLength != 0x7fffffff){				end = _string.substr(pStart + pLength);			}						_string = start + replaced + end;;		}		public function clear():void{			_string = "";		};				public function isEmpty():Boolean{			if (_string.length == 0) return true;
			if (_string == "") return true;
						return isNullOrEmpty(toString());		};				public function toString(pStartIdx:Number = 0, pLength:Number = 0x7fffffff):String{			return _string.substr(pStartIdx, pLength);
		}	}}